"""Home Assistant component for accessing the Wallbox Portal API. The switch component creates a switch entity."""

from __future__ import annotations

from collections.abc import Awaitable, Callable
from dataclasses import dataclass

from requests import HTTPError

from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

from .const import (
    CHARGER_DATA_KEY,
    CHARGER_ECO_SMART_KEY,
    CHARGER_FEATURES_KEY,
    CHARGER_PLAN_KEY,
    CHARGER_POWER_BOOST_KEY,
    CHARGER_SERIAL_NUMBER_KEY,
    DOMAIN,
    EcoSmartMode,
)
from .coordinator import WallboxConfigEntry, WallboxCoordinator
from .entity import WallboxEntity


@dataclass(frozen=True, kw_only=True)
class WallboxSelectEntityDescription(SelectEntityDescription):
    """Describes Wallbox select entity."""

    current_option_fn: Callable[[WallboxCoordinator], str | None]
    select_option_fn: Callable[[WallboxCoordinator, str], Awaitable[None]]
    supported_fn: Callable[[WallboxCoordinator], bool]


SELECT_TYPES: dict[str, WallboxSelectEntityDescription] = {
    CHARGER_ECO_SMART_KEY: WallboxSelectEntityDescription(
        key=CHARGER_ECO_SMART_KEY,
        translation_key=CHARGER_ECO_SMART_KEY,
        options=[
            EcoSmartMode.OFF,
            EcoSmartMode.ECO_MODE,
            EcoSmartMode.FULL_SOLAR,
        ],
        select_option_fn=lambda coordinator, mode: coordinator.async_set_eco_smart(
            mode
        ),
        current_option_fn=lambda coordinator: coordinator.data[CHARGER_ECO_SMART_KEY],
        supported_fn=lambda coordinator: coordinator.data[CHARGER_DATA_KEY][
            CHARGER_PLAN_KEY
        ][CHARGER_FEATURES_KEY].count(CHARGER_POWER_BOOST_KEY),
    )
}


async def async_setup_entry(
    hass: HomeAssistant,
    entry: WallboxConfigEntry,
    async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
    """Create wallbox select entities in HASS."""
    coordinator: WallboxCoordinator = entry.runtime_data
    if coordinator.data[CHARGER_ECO_SMART_KEY] != EcoSmartMode.DISABLED:
        async_add_entities(
            WallboxSelect(coordinator, description)
            for ent in coordinator.data
            if (
                (description := SELECT_TYPES.get(ent))
                and description.supported_fn(coordinator)
            )
        )


# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0


class WallboxSelect(WallboxEntity, SelectEntity):
    """Representation of the Wallbox portal."""

    entity_description: WallboxSelectEntityDescription

    def __init__(
        self,
        coordinator: WallboxCoordinator,
        description: WallboxSelectEntityDescription,
    ) -> None:
        """Initialize a Wallbox select entity."""
        super().__init__(coordinator)
        self.entity_description = description
        self._attr_unique_id = f"{description.key}-{coordinator.data[CHARGER_DATA_KEY][CHARGER_SERIAL_NUMBER_KEY]}"

    @property
    def current_option(self) -> str | None:
        """Return an option."""
        return self.entity_description.current_option_fn(self.coordinator)

    async def async_select_option(self, option: str) -> None:
        """Handle the selection of an option."""
        try:
            await self.entity_description.select_option_fn(self.coordinator, option)
        except (ConnectionError, HTTPError) as e:
            raise HomeAssistantError(
                translation_key="api_failed", translation_domain=DOMAIN
            ) from e
        await self.coordinator.async_request_refresh()
